home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume13 / pas2c.pch < prev    next >
Encoding:
Internet Message Format  |  1988-01-31  |  35.8 KB

  1. Subject:  v13i067:  Patches for Pascal-to-C translator
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Per Bergsten <mcvax!enea!chalmers!holtec!perb>
  7. Posting-number: Volume 13, Issue 67
  8. Archive-name: pas2c.pch
  9.  
  10. The following diffs adress all errors in the Pascal-to-C-translator that have
  11. been reported to me. The translator was posted during summer -87 and a few
  12. bug-reports came in during August. I have had no reports since late September
  13. which I take to mean that either nobody has found any use for the program or
  14. that there are no remaining serious problems.
  15.  
  16. Happily, with one exception, no report concerned cases where the translator
  17. silently produced wrong code. There were some cases where the translator would
  18. fail or where it generated code that was syntactically incorrect.
  19. The exception concerned the status of "input" before the program had tested
  20. "eof". This was actually a "feature" since the behaviour was intended (though
  21. not formally correct).
  22.  
  23. Comments, questions etc to:
  24.  
  25.     Per Bergsten
  26.  
  27.             perb@holtec.se    (....mcvax!enea!chalmers!holtec!perb)
  28.             perb%holtec.uucp@chalmers.csnet
  29.  
  30. -------------------------------------------------------------------------------
  31. #! /bin/sh
  32. # This is a shell archive, meaning:
  33. # 1. Remove everything above the #! /bin/sh line.
  34. # 2. Save the resulting text in a file.
  35. # 3. Execute the file with /bin/sh (not csh) to create the files:
  36. #    READ_ME
  37. #    ptc.diff
  38. export PATH; PATH=/bin:$PATH
  39. if test -f 'READ_ME'
  40. then
  41.     echo shar: will not over-write existing file "'READ_ME'"
  42. else
  43. cat << \SHAR_EOF > 'READ_ME'
  44. The following problems have been adressed.
  45.  
  46.     1)    In some circumstances the reader misread 1..n which lead to
  47.         a complaint about malplaced floating point numbers.
  48.  
  49.     2)    The translator generated double "->" arrows for references to
  50.         VAR-parameters that were pointers.
  51.  
  52.     3)    Missing initialisation of pointers in a record variant for
  53.         case-statements sometimes caused the translator to crash.
  54.  
  55.     4)    Calling "write" with a boolean literal as parameter caused the
  56.         translator to crash.
  57.  
  58.     5)    Initialization of input. Programs that read input before
  59.         testing for eof can be made to work by defining a compiletime
  60.         constant STDINIT otherwise the first returned character will
  61.         be null.
  62.  
  63.     6)    The code generated for procedurecalls with string-literal
  64.         parameters could cause the resulting program to crash due to
  65.         alignment errors. This is truly a PATCH, i.e. the "correct"
  66.         solution would require a redesign of the translator.
  67.  
  68.         In this case the problem has been swept under the carpet at
  69.         the cost of some runtime overhead by copying data.
  70.         The behaviour of the translator is controlled by a boolean
  71.         constant "align" which, if true, cuses the translator to
  72.         generate calls to to functions STRALIGN and SETALIGN.
  73.         STRALIGN and SETALIGN are macros which by default call simple
  74.         subroutines that will copy data to well aligned structures.
  75.  
  76.     7)    Types and variables in nested procedures were not always moved
  77.         to an enclosing scope when the procedures were un-nested.
  78.  
  79.     8)    The I/O macros were modified so that "rewind" was replaced by
  80.         "fseek" and so that the generated code is type-correct.
  81.  
  82.     9)    The translator didn't handle incomplete Pascal programs as
  83.         documented.
  84.  
  85.     10)    A few changes were made to remove illegal Pascal-code.
  86. SHAR_EOF
  87. fi # end of overwriting check
  88. if test -f 'ptc.diff'
  89. then
  90.     echo shar: will not over-write existing file "'ptc.diff'"
  91. else
  92. cat << \SHAR_EOF > 'ptc.diff'
  93. *** ptc.p    Fri Nov 13 18:45:21 1987
  94. --- nptc.p    Fri Nov 13 18:44:29 1987
  95. ***************
  96. *** 42,48 ****
  97.   (**    The code generated by the translator assumes that there    is a      **)
  98.   (**    C-implementation with at least a reasonable <stdio> library      **)
  99.   (**    since all input/output is implemented in terms of C functions      **)
  100. ! (**    like fprintf(), getc(), fopen(), rewind() etc.              **)
  101.   (**    If the source-program uses Pascal functions like sin(), sqrt()      **)
  102.   (**    etc, there must also exist such functions in the C-library.      **)
  103.   (**                                      **)
  104. --- 42,48 ----
  105.   (**    The code generated by the translator assumes that there    is a      **)
  106.   (**    C-implementation with at least a reasonable <stdio> library      **)
  107.   (**    since all input/output is implemented in terms of C functions      **)
  108. ! (**    like fprintf(), getc(), fopen(), fseek() etc.              **)
  109.   (**    If the source-program uses Pascal functions like sin(), sqrt()      **)
  110.   (**    etc, there must also exist such functions in the C-library.      **)
  111.   (**                                      **)
  112. ***************
  113. *** 53,59 ****
  114.   
  115.   label    9999;                (* end of program        *)
  116.   
  117. ! const    version        = '@(#)ptc.p    1.5  Date 87/05/01';
  118.   
  119.       keytablen    = 38;        (* nr of keywords        *)
  120.       keywordlen    = 10;        (* length of a keyword        *)
  121. --- 53,59 ----
  122.   
  123.   label    9999;                (* end of program        *)
  124.   
  125. ! const    version        = '@(#)ptc.p    2.6  Date 87/09/12';
  126.   
  127.       keytablen    = 38;        (* nr of keywords        *)
  128.       keywordlen    = 10;        (* length of a keyword        *)
  129. ***************
  130. *** 67,75 ****
  131.       setbits        = 15;            (* CPU *)
  132.   
  133.       (* a Pascal file is implemented as a struct which (among other    *)
  134. !     (* things) contain a flag-field, currently 3 bits are used    *)
  135.       filebits    = 'unsigned short';    (* flags for files    *)
  136. !     filefill    = 12;            (* 16 less used 3 bits    *)
  137.   
  138.       maxsetrange    = 15;            (* nr of words in a set    *)
  139.       scalbase    = 0;    (* ordinal value of first scalar member    *)
  140. --- 67,75 ----
  141.       setbits        = 15;            (* CPU *)
  142.   
  143.       (* a Pascal file is implemented as a struct which (among other    *)
  144. !     (* things) contain a flag-field, currently 4 bits are used    *)
  145.       filebits    = 'unsigned short';    (* flags for files    *)
  146. !     filefill    = 12;            (* 16 less used 4 bits    *)
  147.   
  148.       maxsetrange    = 15;            (* nr of words in a set    *)
  149.       scalbase    = 0;    (* ordinal value of first scalar member    *)
  150. ***************
  151. *** 106,111 ****
  152. --- 106,112 ----
  153.          temporary files for reset/rewrite, the last character is supplied
  154.          by the reset/rewrite routine *)
  155.       tmpfilename    = '"/tmp/ptc%d%c", getpid(), '; (* OS *)
  156. +     maxfilename    = 'MAXFILENAME';
  157.   
  158.       (* some frequently used characters *)
  159.       space        = ' ';
  160. ***************
  161. *** 146,151 ****
  162. --- 147,154 ----
  163.       voidtyp        = 'void';    (* for procedures         *)
  164.       voidcast    = '(void)';
  165.   
  166. +     align        = true;        (* align literal params        *)
  167.       intlen        = 10;        (* length of written integer    *)
  168.       fixlen        = 20;        (* length of written real    *)
  169.   
  170. ***************
  171. *** 239,244 ****
  172. --- 242,264 ----
  173.             sinteger:    (vint    : integer);
  174.             sreal:    (vflt    : strindx);
  175.             sstring:    (vstr    : strindx);
  176. +           sand,        sarray,        sbegin,        scase,
  177. +           sconst,    sdiv,        sdo,        sdownto,
  178. +           selse,    send,        sextern,    sfile,
  179. +           sfor,        sforward,    sfunc,        sgoto,
  180. +           sif,        sinn,        slabel,        smod,
  181. +           snil,        snot,        sof,        sor,
  182. +           sother,    spacked,    sproc,        spgm,
  183. +           srecord,    srepeat,    sset,        sthen,
  184. +           sto,        stype,        suntil,        svar,
  185. +           swhile,    swith,        seof,
  186. +           splus,    sminus,        smul,        squot,
  187. +           sarrow,    slpar,        srpar,        slbrack,
  188. +           srbrack,    seq,        sne,        slt,
  189. +           sle,        sgt,        sge,        scomma,
  190. +           scolon,    ssemic,        sassign,    sdotdot,
  191. +           sdot:        ()
  192.           end;
  193.   
  194.       (* enumeration of symnode variants *)
  195. ***************
  196. *** 648,653 ****
  197. --- 668,674 ----
  198.           cstdout,    cstderr,    cstrncmp,    cstrncpy,
  199.           cstruct,    cstatic,    cswitch,    ctypedef,
  200.           cundef,        cungetc,    cunion,        cunlink,
  201. +         cfseek,        cgetchar,    cputchar,
  202.           cunsigned,    cwrite
  203.       );
  204.   
  205. ***************
  206. *** 661,667 ****
  207.           enew,        esetbase,    esetsize,    eoverflow,
  208.           etree,        etag,        euprconf,    easgnconf,
  209.           ecmpconf,    econfconf,    evrntfile,    evarfile,
  210. !         emanymachs,    ebadmach
  211.       );
  212.   
  213.       machdefstr = packed array [ 1 .. machdeflen ] of char;
  214. --- 682,688 ----
  215.           enew,        esetbase,    esetsize,    eoverflow,
  216.           etree,        etag,        euprconf,    easgnconf,
  217.           ecmpconf,    econfconf,    evrntfile,    evarfile,
  218. !         emanymachs,    ebadmach,    eprconf
  219.       );
  220.   
  221.       machdefstr = packed array [ 1 .. machdeflen ] of char;
  222. ***************
  223. *** 683,688 ****
  224. --- 704,711 ----
  225.       useins,
  226.       usescpy,
  227.       usecomp,        (* source program uses string-compare    *)
  228. +     usealig,        (* source program uses aligned params    *)
  229. +     usesal,
  230.       usefopn,        (* source program uses reset/rewrite    *)
  231.       usescan,
  232.       usegetl,
  233. ***************
  234. *** 738,745 ****
  235.   
  236.       varno    : integer;        (* counter for unique id's    *)
  237.   
  238. !     hexdig    : packed array [ 0 .. 15 ] of char;
  239.   
  240.   (*    Prtmsg produces an error message. It asssumes that procedure    *)
  241.   (*    "message" (predefined) will "writeln" to user tty. OS        *)
  242.   procedure prtmsg(m : errors);
  243. --- 761,771 ----
  244.   
  245.       varno    : integer;        (* counter for unique id's    *)
  246.   
  247. !     pushchr    : char;            (* pushback for lexical scanner    *)
  248. !     pushed    : boolean;
  249.   
  250. +     hexdig    : array [ 0 .. 15 ] of char;
  251.   (*    Prtmsg produces an error message. It asssumes that procedure    *)
  252.   (*    "message" (predefined) will "writeln" to user tty. OS        *)
  253.   procedure prtmsg(m : errors);
  254. ***************
  255. *** 814,819 ****
  256. --- 840,847 ----
  257.           message(restr, 'Too many machine integer types');
  258.         ebadmach:
  259.           message(inter, 'Bad name for machine integer type');
  260. +       eprconf:
  261. +         message(restr, 'Cannot write conformant arrays');
  262.       end;(* case *)
  263.       if lastline <> 0 then
  264.           begin
  265. ***************
  266. *** 1219,1225 ****
  267.       var    c    : char;
  268.   
  269.       begin
  270. !         if eof then
  271.               c := chr(null)
  272.           else begin
  273.               colno := colno + 1;
  274. --- 1247,1258 ----
  275.       var    c    : char;
  276.   
  277.       begin
  278. !         if pushed then
  279. !             begin
  280. !             c := pushchr;
  281. !             pushed := false
  282. !             end
  283. !         else if eof then
  284.               c := chr(null)
  285.           else begin
  286.               colno := colno + 1;
  287. ***************
  288. *** 1235,1241 ****
  289.                   else
  290.                       write(c);
  291.               if c = tab1 then
  292. !                 colno := ((colno div tabwidth) + 1) * tabwidth
  293.                end;
  294.           if lastchr > 0 then
  295.               begin
  296. --- 1268,1275 ----
  297.                   else
  298.                       write(c);
  299.               if c = tab1 then
  300. !                 colno := (((colno - 1) div tabwidth) + 1) *
  301. !                         tabwidth
  302.                end;
  303.           if lastchr > 0 then
  304.               begin
  305. ***************
  306. *** 1249,1255 ****
  307.       function peekchar : char;
  308.   
  309.       begin
  310. !         if eof then
  311.               peekchar := chr(null)
  312.           else
  313.               peekchar := input^
  314. --- 1283,1291 ----
  315.       function peekchar : char;
  316.   
  317.       begin
  318. !         if pushed then
  319. !             peekchar := pushchr
  320. !         else if eof then
  321.               peekchar := chr(null)
  322.           else
  323.               peekchar := input^
  324. ***************
  325. *** 1458,1466 ****
  326.                       end;
  327.                   st := sinteger;
  328.                   vint := n;
  329.                   if realok then
  330.                       begin
  331. -                     (* accept real numbers *)
  332.                       if peekchar = '.' then
  333.                           begin
  334.                           (* this is a real number *)
  335. --- 1494,1508 ----
  336.                       end;
  337.                   st := sinteger;
  338.                   vint := n;
  339. +                 if realok and (peekchar = '.') then
  340. +                     begin
  341. +                     c := nextchar;
  342. +                     realok := numchar(peekchar);
  343. +                     pushchr := c;
  344. +                     pushed := true
  345. +                     end;
  346.                   if realok then
  347.                       begin
  348.                       if peekchar = '.' then
  349.                           begin
  350.                           (* this is a real number *)
  351. ***************
  352. *** 1579,1585 ****
  353.                 quote:
  354.                   begin
  355.                   (* assume the symbol is a literal string *)
  356. !                 wl := 0;
  357.                   ready := false;
  358.                   repeat
  359.                       if eoln then
  360. --- 1621,1627 ----
  361.                 quote:
  362.                   begin
  363.                   (* assume the symbol is a literal string *)
  364. !                 wl := 1;
  365.                   ready := false;
  366.                   repeat
  367.                       if eoln then
  368. ***************
  369. *** 1602,1608 ****
  370.                           end;
  371.                       if not ready then
  372.                           begin
  373. !                         wl := wl + 1;
  374.                           if wl >= maxtoknlen then
  375.                               begin
  376.                               lasttok[lastchr] :=
  377. --- 1644,1650 ----
  378.                           end;
  379.                       if not ready then
  380.                           begin
  381. !                         wb[wl] := c;
  382.                           if wl >= maxtoknlen then
  383.                               begin
  384.                               lasttok[lastchr] :=
  385. ***************
  386. *** 1609,1618 ****
  387.                                   chr(null);
  388.                               error(elongstring)
  389.                               end;
  390. !                         wb[wl] := c
  391.                           end
  392.                   until    ready;
  393. !                 if wl = 1 then
  394.                       begin
  395.                       (* only 1 character => not a string *)
  396.                       st := schar;
  397. --- 1651,1660 ----
  398.                                   chr(null);
  399.                               error(elongstring)
  400.                               end;
  401. !                         wl := wl + 1;
  402.                           end
  403.                   until    ready;
  404. !                 if wl = 2 then
  405.                       begin
  406.                       (* only 1 character => not a string *)
  407.                       st := schar;
  408. ***************
  409. *** 1620,1631 ****
  410.                       end
  411.                   else begin
  412.                       (* > 1 character => its a string *)
  413. -                     wl := wl + 1;
  414. -                     if wl >= maxtoknlen then
  415. -                         begin
  416. -                         lasttok[lastchr] := chr(null);
  417. -                         error(elongstring)
  418. -                         end;
  419.                       wb[wl] := chr(null);
  420.                       st := sstring;
  421.                       vstr := savestr(wb)
  422. --- 1662,1667 ----
  423. ***************
  424. *** 2645,2650 ****
  425. --- 2681,2687 ----
  426.                           sproc, sfunc, sbegin]);
  427.           pbody(tp);
  428.           checksymbol([sdot]);
  429. +         nextsymbol([seof]);
  430.           tp^.tscope := currscope;
  431.           leavescope;
  432.           pprogram := tp
  433. ***************
  434. *** 2662,2668 ****
  435.           tp^.tsubid := nil;
  436.           tp^.tsubpar := nil;
  437.           pbody(tp);
  438. !         checksymbol([ssemic]);
  439.           tp^.tscope := currscope;
  440.           leavescope;
  441.           pmodule := tp
  442. --- 2699,2707 ----
  443.           tp^.tsubid := nil;
  444.           tp^.tsubpar := nil;
  445.           pbody(tp);
  446. !         checksymbol([ssemic, seof]);
  447. !         if currsym.st = ssemic then
  448. !             nextsymbol([seof]);
  449.           tp^.tscope := currscope;
  450.           leavescope;
  451.           pmodule := tp
  452. ***************
  453. *** 2799,2805 ****
  454.               enterscope(dp);
  455.               dp := currscope
  456.               end;
  457. !         nextsymbol([sid, scase] + [cs]);
  458.           tq := nil;
  459.           while currsym.st = sid do
  460.               begin
  461. --- 2838,2844 ----
  462.               enterscope(dp);
  463.               dp := currscope
  464.               end;
  465. !         nextsymbol([sid, scase, cs]);
  466.           tq := nil;
  467.           while currsym.st = sid do
  468.               begin
  469. ***************
  470. *** 2820,2826 ****
  471.               tq^.tbind := ptypedef;
  472.               enterscope(dp);
  473.               if currsym.st = ssemic then
  474. !                 nextsymbol([sid, scase] + [cs])
  475.               end;
  476.           if currsym.st = scase then
  477.               begin
  478. --- 2859,2865 ----
  479.               tq^.tbind := ptypedef;
  480.               enterscope(dp);
  481.               if currsym.st = ssemic then
  482. !                 nextsymbol([sid, scase, cs])
  483.               end;
  484.           if currsym.st = scase then
  485.               begin
  486. ***************
  487. *** 2852,2858 ****
  488.                   tv := nil;
  489.                   repeat
  490.                       nextsymbol([sid, sinteger, schar, splus,
  491. !                              sminus] + [cs]);
  492.                       if currsym.st = cs then
  493.                           goto 999;
  494.                       if tv = nil then
  495. --- 2891,2897 ----
  496.                   tv := nil;
  497.                   repeat
  498.                       nextsymbol([sid, sinteger, schar, splus,
  499. !                              sminus, cs]);
  500.                       if currsym.st = cs then
  501.                           goto 999;
  502.                       if tv = nil then
  503. ***************
  504. *** 3650,3655 ****
  505. --- 3689,3696 ----
  506.                   tq^.tnext := mknode(nchoise);
  507.                   tq := tq^.tnext
  508.                    end;
  509. +             tq^.tchocon := nil;
  510. +             tq^.tchostmt := nil;
  511.               tv := nil;
  512.               repeat
  513.                   nextsymbol([sid, sinteger, schar,
  514. ***************
  515. *** 3845,3852 ****
  516.       if currsym.st = spgm then
  517.           top := pprogram
  518.       else
  519. !         top := pmodule;
  520. !     nextsymbol([seof]);
  521.   end;    (* parse *)
  522.   
  523.   (*    Compute value for a node (which must be some kind of constant).    *)
  524. --- 3886,3892 ----
  525.       if currsym.st = spgm then
  526.           top := pprogram
  527.       else
  528. !         top := pmodule
  529.   end;    (* parse *)
  530.   
  531.   (*    Compute value for a node (which must be some kind of constant).    *)
  532. ***************
  533. *** 4317,4328 ****
  534.                           move := true;
  535.                           sp := ip^.tsym;
  536.                           if sp^.lid^.inref > 1 then
  537. -                           begin
  538.                               sp^.lid :=
  539. !                             mkrename( 'M', sp^.lid);
  540. !                             sp^.lid^.inref :=
  541. !                                 sp^.lid^.inref - 1
  542. !                           end;
  543.                           ip := nil
  544.                           end
  545.                       else
  546. --- 4357,4364 ----
  547.                           move := true;
  548.                           sp := ip^.tsym;
  549.                           if sp^.lid^.inref > 1 then
  550.                               sp^.lid :=
  551. !                             mkrename('M', sp^.lid);
  552.                           ip := nil
  553.                           end
  554.                       else
  555. ***************
  556. *** 4619,4624 ****
  557. --- 4655,4662 ----
  558.   
  559.                   (* mark those used in nested subroutines *)
  560.                   global(tp^.tsubsub, tp, false);
  561. +                 global(tp^.tsubvar, tp, false);
  562. +                 global(tp^.tsubtype, tp, false);
  563.   
  564.                   (* move out variables used in inner scope *)
  565.                   movevars(tp, tp^.tsubpar);
  566. ***************
  567. *** 4887,4896 ****
  568.                      a unique name *)
  569.                   sp := tp^.tsubid^.tsym;
  570.                   if sp^.lid^.inref > 1 then
  571. !                     begin
  572. !                     sp^.lid := mkrename('P', sp^.lid);
  573. !                     sp^.lid^.inref := sp^.lid^.inref - 1
  574. !                     end
  575.                   end;
  576.               tp := tp^.tnext
  577.               end
  578. --- 4925,4931 ----
  579.                      a unique name *)
  580.                   sp := tp^.tsubid^.tsym;
  581.                   if sp^.lid^.inref > 1 then
  582. !                     sp^.lid := mkrename('P', sp^.lid)
  583.                   end;
  584.               tp := tp^.tnext
  585.               end
  586. ***************
  587. *** 5131,5136 ****
  588. --- 5166,5172 ----
  589.   
  590.   const    include    = '# include ';
  591.       define    = '# define ';
  592. +     undef    = '# undef ';
  593.       ifdef    = '# ifdef ';
  594.       ifndef    = '# ifndef ';
  595.       elsif    = '# else';
  596. ***************
  597. *** 5145,5152 ****
  598.   var    conflag,
  599.       setused,
  600.       dropset,
  601. -     donearr    : boolean;
  602.       doarrow,
  603.       indnt    : integer;
  604.   
  605.       procedure increment;
  606. --- 5181,5188 ----
  607.   var    conflag,
  608.       setused,
  609.       dropset,
  610.       doarrow,
  611. +     donearr    : boolean;
  612.       indnt    : integer;
  613.   
  614.       procedure increment;
  615. ***************
  616. *** 5203,5216 ****
  617.       (*    Emit code to select a record member.    *)
  618.       procedure eselect(tp : treeptr);
  619.   
  620.       begin
  621. !         doarrow := doarrow + 1;
  622.           eexpr(tp);
  623. -         doarrow := doarrow - 1;
  624.           if donearr then
  625.               donearr := false
  626.           else
  627. !             write('.')
  628.       end;
  629.   
  630.       (*    Emit code for call to a predefined function/procedure.    *)
  631. --- 5239,5255 ----
  632.       (*    Emit code to select a record member.    *)
  633.       procedure eselect(tp : treeptr);
  634.   
  635. +     var    da    : boolean;
  636.       begin
  637. !         da := doarrow;
  638. !         doarrow := true;
  639.           eexpr(tp);
  640.           if donearr then
  641.               donearr := false
  642.           else
  643. !             write('.');
  644. !         doarrow := da
  645.       end;
  646.   
  647.       (*    Emit code for call to a predefined function/procedure.    *)
  648. ***************
  649. *** 5435,5441 ****
  650.                           else
  651.                               write('*.*');
  652.                       write('s')
  653. !                      end
  654.               end (* case *)
  655.           end;    (* eformat *)
  656.   
  657. --- 5474,5482 ----
  658.                           else
  659.                               write('*.*');
  660.                       write('s')
  661. !                      end;
  662. !               'v':
  663. !                 fatal(eprconf)
  664.               end (* case *)
  665.           end;    (* eformat *)
  666.   
  667. ***************
  668. *** 5572,5578 ****
  669.                       write(', ');
  670.                       eexpr(tq)
  671.                       end
  672. !                 end
  673.               end (* case *)
  674.           end;    (* ewrite *)
  675.   
  676. --- 5613,5621 ----
  677.                       write(', ');
  678.                       eexpr(tq)
  679.                       end
  680. !                 end;
  681. !               'v':
  682. !                 fatal(eprconf)
  683.               end (* case *)
  684.           end;    (* ewrite *)
  685.   
  686. ***************
  687. *** 6212,6218 ****
  688.               write(', ');
  689.               tq := tp^.taparm^.tnext;
  690.               if tq = nil then
  691. !                 write('NULL')
  692.               else begin
  693.                   tq := typeof(tq);
  694.                   if tq = typnods[tchar] then
  695. --- 6255,6261 ----
  696.               write(', ');
  697.               tq := tp^.taparm^.tnext;
  698.               if tq = nil then
  699. !                 write('NULL, 0')
  700.               else begin
  701.                   tq := typeof(tq);
  702.                   if tq = typnods[tchar] then
  703. ***************
  704. *** 6221,6234 ****
  705.                       ch := chr(cvalof(tp^.taparm^.tnext));
  706.                       if (ch = bslash) or (ch = cite) then
  707.                           write(bslash);
  708. !                     write(ch, cite)
  709.                       end
  710.                   else if tq = typnods[tstring] then
  711. !                     eexpr(tp^.taparm^.tnext)
  712. !                 else  if tq^.tt in [narray, nconfarr] then
  713.                        begin
  714.                       eexpr(tp^.taparm^.tnext);
  715. !                     write('.A')
  716.                        end
  717.                   else
  718.                       fatal(etree)
  719. --- 6264,6282 ----
  720.                       ch := chr(cvalof(tp^.taparm^.tnext));
  721.                       if (ch = bslash) or (ch = cite) then
  722.                           write(bslash);
  723. !                     write(ch, cite, ', -1')
  724.                       end
  725.                   else if tq = typnods[tstring] then
  726. !                     begin
  727. !                     eexpr(tp^.taparm^.tnext);
  728. !                     write(', -1')
  729. !                     end
  730. !                 else if tq^.tt = narray then
  731.                        begin
  732.                       eexpr(tp^.taparm^.tnext);
  733. !                     write('.A, sizeof(');
  734. !                     eexpr(tp^.taparm^.tnext);
  735. !                     write('.A)')
  736.                        end
  737.                   else
  738.                       fatal(etree)
  739. ***************
  740. *** 6487,6507 ****
  741.                           eexpr(tq);
  742.                           write(')')
  743.                           end
  744.                       else
  745.                           eexpr(tq);
  746.                       end
  747. !                 else if (tx = typnods[tstring]) or
  748. !                         (tx = typnods[tset]) then
  749.                       begin
  750. -                     (* cast literal to proper type *)
  751.                       write('*((');
  752.                       etypedef(tf^.tup^.tbind);
  753.                       write(' *)');
  754. !                     if tx = typnods[tset] then
  755.                           begin
  756. !                         dropset := true;
  757.                           eexpr(tq);
  758. !                         dropset := false
  759.                           end
  760.                       else
  761.                           eexpr(tq);
  762. --- 6535,6574 ----
  763.                           eexpr(tq);
  764.                           write(')')
  765.                           end
  766. +                     else if tf^.tup^.tt = nvarpar then
  767. +                         eaddr(tq)
  768.                       else
  769. +                         eexpr(tq)
  770. +                     end
  771. +                 else if tx = typnods[tset] then
  772. +                     begin
  773. +                     write('*((');
  774. +                     etypedef(tf^.tup^.tbind);
  775. +                     write(' *)');
  776. +                     dropset := true;
  777. +                     if align then
  778. +                         begin
  779. +                         usesal := true;
  780. +                         write('SETALIGN(');
  781.                           eexpr(tq);
  782. +                         write(')')
  783. +                         end
  784. +                     else
  785. +                         eexpr(tq);
  786. +                     dropset := false;
  787. +                     write(')')
  788.                       end
  789. !                 else if tx = typnods[tstring] then
  790.                       begin
  791.                       write('*((');
  792.                       etypedef(tf^.tup^.tbind);
  793.                       write(' *)');
  794. !                     if align then
  795.                           begin
  796. !                         usealig := true;
  797. !                         write('STRALIGN(');
  798.                           eexpr(tq);
  799. !                         write(')')
  800.                           end
  801.                       else
  802.                           eexpr(tq);
  803. ***************
  804. *** 6521,6528 ****
  805.                       eexpr(tq);
  806.                       (* add upper bound of actual value *)
  807.                       if tq^.tnext = nil then
  808. !                         write(', ',
  809. !                             crange(tx^.taindx):1)
  810.                       end
  811.                   else begin
  812.                       if tf^.tup^.tt = nvarpar then
  813. --- 6588,6600 ----
  814.                       eexpr(tq);
  815.                       (* add upper bound of actual value *)
  816.                       if tq^.tnext = nil then
  817. !                         begin
  818. !                         write(', (');
  819. !                         eexpr(tx^.taindx^.thi);
  820. !                         write(' - ');
  821. !                         eexpr(tx^.taindx^.tlo);
  822. !                         write(' + 1)')
  823. !                         end
  824.                       end
  825.                   else begin
  826.                       if tf^.tup^.tt = nvarpar then
  827. ***************
  828. *** 6930,6944 ****
  829.                   eexpr(tp^.texps);
  830.                   write('.buf')
  831.                   end
  832. !             else if doarrow = 0 then
  833.                   begin
  834. !                 write('*');
  835. !                 eexpr(tp^.texps)
  836. !                 end
  837. !             else begin
  838.                   eexpr(tp^.texps);
  839.                   write('->');
  840.                   donearr := true
  841.                    end
  842.               end;
  843.             nid:
  844. --- 7002,7018 ----
  845.                   eexpr(tp^.texps);
  846.                   write('.buf')
  847.                   end
  848. !             else if doarrow then
  849.                   begin
  850. !                 doarrow := false;
  851.                   eexpr(tp^.texps);
  852.                   write('->');
  853.                   donearr := true
  854. +                 end
  855. +             else begin
  856. +                 write('(*');
  857. +                 eexpr(tp^.texps);
  858. +                 write(')')
  859.                    end
  860.               end;
  861.             nid:
  862. ***************
  863. *** 6947,6966 ****
  864.                  var-parameter or as a procedure-parameter *)
  865.               tq := idup(tp);
  866.               if tq^.tt = nvarpar then
  867. !                 begin
  868. !                 if (doarrow = 0) or
  869. !                         (tq^.tattr = areference) then
  870.                       begin
  871. !                     write('(*');
  872.                       printid(tp^.tsym^.lid);
  873. !                     write(')')
  874.                       end
  875.                   else begin
  876.                       printid(tp^.tsym^.lid);
  877. !                     write('->');
  878. !                     donearr := true
  879.                        end
  880. -                 end
  881.               else if (tq^.tt = nconst) and conflag then
  882.                   write(cvalof(tp):1)
  883.               else if tq^.tt in [nparproc, nparfunc] then
  884. --- 7021,7038 ----
  885.                  var-parameter or as a procedure-parameter *)
  886.               tq := idup(tp);
  887.               if tq^.tt = nvarpar then
  888. !                 if doarrow then
  889.                       begin
  890. !                     doarrow := false;
  891.                       printid(tp^.tsym^.lid);
  892. !                     write('->');
  893. !                     donearr := true
  894.                       end
  895.                   else begin
  896. +                     write('(*');
  897.                       printid(tp^.tsym^.lid);
  898. !                     write(')')
  899.                        end
  900.               else if (tq^.tt = nconst) and conflag then
  901.                   write(cvalof(tp):1)
  902.               else if tq^.tt in [nparproc, nparfunc] then
  903. ***************
  904. *** 7107,7112 ****
  905. --- 7179,7206 ----
  906.               end
  907.       end;    (* econst *)
  908.   
  909. +     (*    Undefine constants.                    *)
  910. +     procedure edconst(tp : treeptr);
  911. +     var    sp    : symptr;
  912. +     begin
  913. +         while tp <> nil do
  914. +             begin
  915. +             sp := tp^.tidl^.tsym;
  916. +             if tp^.tbind^.tt <> nstring then
  917. +                 begin
  918. +                 (* all non-strings are emitted as
  919. +                    preprocessor # defines *)
  920. +                 write(undef);
  921. +                 printid(sp^.lid);
  922. +                 writeln
  923. +                 end;
  924. +             tp := tp^.tnext
  925. +             end
  926. +     end;    (* edconst *)
  927.       (*    Emit a typedef.                        *)
  928.       procedure etypedef;
  929.   
  930. ***************
  931. *** 7867,7876 ****
  932.                 ncase:
  933.                   begin
  934.                   indent;
  935. !                 write('switch (');
  936.                   increment;
  937.                   eexpr(tp^.tcasxp);
  938. !                 writeln(') {');
  939.                   decrement;
  940.                   echoise(tp^.tcaslst);
  941.                   indent;
  942. --- 7961,7970 ----
  943.                 ncase:
  944.                   begin
  945.                   indent;
  946. !                 write('switch ((int)(');
  947.                   increment;
  948.                   eexpr(tp^.tcasxp);
  949. !                 writeln(')) {');
  950.                   decrement;
  951.                   echoise(tp^.tcaslst);
  952.                   indent;
  953. ***************
  954. *** 8052,8058 ****
  955.               indent;
  956.               writeln('  case 0:');
  957.               indent;
  958. !             writeln(tab1, 'break');
  959.               tq := tp^.tsublab;
  960.               while tq <> nil do
  961.                   begin
  962. --- 8146,8152 ----
  963.               indent;
  964.               writeln('  case 0:');
  965.               indent;
  966. !             writeln(tab1, 'break;');
  967.               tq := tp^.tsublab;
  968.               while tq <> nil do
  969.                   begin
  970. ***************
  971. *** 8071,8077 ****
  972.               indent;
  973.               writeln('  default:');
  974.               indent;
  975. !             writeln(tab1, 'Caseerror(Line)');
  976.               indent;
  977.               writeln('}')
  978.               end
  979. --- 8165,8171 ----
  980.               indent;
  981.               writeln('  default:');
  982.               indent;
  983. !             writeln(tab1, 'Caseerror(Line);');
  984.               indent;
  985.               writeln('}')
  986.               end
  987. ***************
  988. *** 8198,8203 ****
  989. --- 8292,8298 ----
  990.                   writeln(';');
  991.                   end;
  992.               decrement;
  993. +             edconst(tp^.tsubconst);
  994.               writeln('}');
  995.           999:
  996.               writeln;
  997. ***************
  998. *** 8337,8345 ****
  999.               writeln(define, 'Putl(f, v) (f).eoln = v')
  1000.               end;
  1001.           if use(dreset) or use(drewrite) or use(dclose) then
  1002.               writeln(define, 'Finish(f) ((f).out && !(f).eoln) ? ',
  1003.                   '(Putchr(', nlchr, ', f), 0) : 0, ',
  1004. !                     'rewind((f).fp)');    (* LIB *)
  1005.           if use(dclose) then
  1006.               begin
  1007.               writeln(define, 'Close(f) (f).init = ',
  1008. --- 8432,8443 ----
  1009.               writeln(define, 'Putl(f, v) (f).eoln = v')
  1010.               end;
  1011.           if use(dreset) or use(drewrite) or use(dclose) then
  1012. +             begin
  1013.               writeln(define, 'Finish(f) ((f).out && !(f).eoln) ? ',
  1014.                   '(Putchr(', nlchr, ', f), 0) : 0, ',
  1015. !                     '!fseek((f).fp, 0L, 0)'); (* LIB *)
  1016. !             writeln(xtern, 'int', tab1, 'fseek();')    (* LIB *)
  1017. !             end;
  1018.           if use(dclose) then
  1019.               begin
  1020.               writeln(define, 'Close(f) (f).init = ',
  1021. ***************
  1022. *** 8359,8371 ****
  1023.               writeln(elsif);
  1024.               writeln(static, chartyp, tab1, 'Rmode[] = "r+";');
  1025.               writeln(endif);
  1026. !             writeln(define, 'Reset(f, n) (f).init = ',
  1027. !                 '(f).init ? rewind((f).fp) : ',    (* LIB *)
  1028. !                 '(((f).fp = Fopen(n, Rmode)), 1), ',
  1029.                       '(f).eof = (f).out = 0, Get(f)');
  1030. !             writeln(define, 'Resetx(f, n) (f).init = ',
  1031.                   '(f).init ? (Finish(f)) : ',
  1032. !                 '(((f).fp = Fopen(n, Rmode)), 1), ',
  1033.                       '(f).eof = (f).out = 0, Getx(f)');
  1034.               usefopn := true
  1035.               end;
  1036. --- 8457,8469 ----
  1037.               writeln(elsif);
  1038.               writeln(static, chartyp, tab1, 'Rmode[] = "r+";');
  1039.               writeln(endif);
  1040. !             writeln(define, 'Reset(f, n, l) (f).init = ',
  1041. !                 '(f).init ? !fseek((f).fp, 0L, 0) : ', (* LIB *)
  1042. !                 '(((f).fp = Fopen(n, l, Rmode)), 1), ',
  1043.                       '(f).eof = (f).out = 0, Get(f)');
  1044. !             writeln(define, 'Resetx(f, n, l) (f).init = ',
  1045.                   '(f).init ? (Finish(f)) : ',
  1046. !                 '(((f).fp = Fopen(n, l, Rmode)), 1), ',
  1047.                       '(f).eof = (f).out = 0, Getx(f)');
  1048.               usefopn := true
  1049.               end;
  1050. ***************
  1051. *** 8376,8388 ****
  1052.               writeln(elsif);
  1053.               writeln(static, chartyp, tab1, 'Wmode[] = "w+";');
  1054.               writeln(endif);
  1055. !             writeln(define, 'Rewrite(f, n) (f).init = ',
  1056. !                 '(f).init ? rewind((f).fp) : ',    (* LIB *)
  1057. !                 '(((f).fp = Fopen(n, Wmode)), 1), ',
  1058.                       '(f).out = (f).eof = 1');
  1059. !             writeln(define, 'Rewritex(f, n) (f).init = ',
  1060.                   '(f).init ? (Finish(f)) : ',
  1061. !                 '(((f).fp = Fopen(n, Wmode)), 1), ',
  1062.                       '(f).out = (f).eof = (f).eoln = 1');
  1063.               usefopn := true
  1064.               end;
  1065. --- 8474,8486 ----
  1066.               writeln(elsif);
  1067.               writeln(static, chartyp, tab1, 'Wmode[] = "w+";');
  1068.               writeln(endif);
  1069. !             writeln(define, 'Rewrite(f, n, l) (f).init = ',
  1070. !                 '(f).init ? !fseek((f).fp, 0L, 0) : ', (* LIB *)
  1071. !                 '(((f).fp = Fopen(n, l, Wmode)), 1), ',
  1072.                       '(f).out = (f).eof = 1');
  1073. !             writeln(define, 'Rewritex(f, n, l) (f).init = ',
  1074.                   '(f).init ? (Finish(f)) : ',
  1075. !                 '(((f).fp = Fopen(n, l, Wmode)), 1), ',
  1076.                       '(f).out = (f).eof = (f).eoln = 1');
  1077.               usefopn := true
  1078.               end;
  1079. ***************
  1080. *** 8389,8395 ****
  1081.           if usefopn then
  1082.               begin
  1083.               writeln('FILE    *Fopen();');
  1084. !             writeln(define, 'MAXFILENAME 256')
  1085.               end;
  1086.           if usecase or usejmps then
  1087.               begin
  1088. --- 8487,8495 ----
  1089.           if usefopn then
  1090.               begin
  1091.               writeln('FILE    *Fopen();');
  1092. !             writeln(ifndef, maxfilename);
  1093. !             writeln(define, maxfilename, ' ', (maxtoknlen+1):1);
  1094. !             writeln(endif)
  1095.               end;
  1096.           if usecase or usejmps then
  1097.               begin
  1098. ***************
  1099. *** 8443,8449 ****
  1100.               write(' (');
  1101.               printid(defnams[dboolean]^.lid);
  1102.               writeln(')1');
  1103. !             writeln(xtern, chartyp, tab1, '*Bools[];')
  1104.               end;
  1105.           capital(defnams[dinteger]);
  1106.           if use(dinteger) then
  1107. --- 8543,8549 ----
  1108.               write(' (');
  1109.               printid(defnams[dboolean]^.lid);
  1110.               writeln(')1');
  1111. !             writeln(chartyp, tab1, '*Bools[];')
  1112.               end;
  1113.           capital(defnams[dinteger]);
  1114.           if use(dinteger) then
  1115. ***************
  1116. *** 8519,8527 ****
  1117.               writeln(setptyp, tab1, 'Insmem(), Mksubr();');
  1118.               writeln(setptyp, tab1, 'Currset(), Inter();');
  1119.               writeln(static, setptyp, tab1, 'Tmpset;');
  1120. !             writeln(xtern, setptyp, tab1, 'Conset[];');
  1121.               writeln(voidtyp, tab1, 'Setncpy();')
  1122.               end;
  1123.           writeln(xtern, chartyp, ' *strncpy();');    (* LIB *)
  1124.           if use(dargc) or use(dargv) then
  1125.               begin
  1126. --- 8619,8640 ----
  1127.               writeln(setptyp, tab1, 'Insmem(), Mksubr();');
  1128.               writeln(setptyp, tab1, 'Currset(), Inter();');
  1129.               writeln(static, setptyp, tab1, 'Tmpset;');
  1130. !             writeln(setptyp, tab1, 'Conset[];');
  1131.               writeln(voidtyp, tab1, 'Setncpy();')
  1132.               end;
  1133. +         if align then                    (* CPU *)
  1134. +             begin
  1135. +             writeln(ifndef, 'SETALIGN');
  1136. +             writeln(define, 'SETALIGN(x) Alignset(x)');
  1137. +             writeln('struct Set { ', wordtype, tab1, 'S[',
  1138. +                     maxsetrange:1, '+1]; } *Alignset();');
  1139. +             writeln(endif);
  1140. +             writeln(ifndef, 'STRALIGN');
  1141. +             writeln(define, 'STRALIGN(x) Alignstr(x)');
  1142. +             writeln('struct String { char    A[',
  1143. +                     maxtoknlen:1, '+1]; } *Alignstr();');
  1144. +             writeln(endif)
  1145. +             end;
  1146.           writeln(xtern, chartyp, ' *strncpy();');    (* LIB *)
  1147.           if use(dargc) or use(dargv) then
  1148.               begin
  1149. ***************
  1150. *** 8577,8589 ****
  1151. --- 8690,8711 ----
  1152.                   writeln('main()');
  1153.                   writeln('{')
  1154.                    end;
  1155. +             if use(dinput) then
  1156. +                 begin
  1157. +                 writeln(ifdef, 'STDINIT');
  1158. +                 writeln(tab1, voidcast, '(Getx(input));');
  1159. +                 writeln(endif)
  1160. +                 end;
  1161.               increment;
  1162.               elabel(tp);
  1163.               estmt(tp^.tsubstmt);
  1164.               indent;
  1165.               writeln('exit(0);');
  1166. +             indent;
  1167. +             writeln('/', '* NOTREACHED *', '/');
  1168.               decrement;
  1169.               writeln('}');
  1170. +             edconst(tp^.tsubconst);
  1171.               writeln('/', '*');
  1172.               writeln('**    End of program code');
  1173.               writeln('*', '/')
  1174. ***************
  1175. *** 8716,8725 ****
  1176.       conflag := false;
  1177.       setused := false;
  1178.       dropset := false;
  1179. !     doarrow := 0;
  1180.       eprogram(top);
  1181.       if usebool then
  1182. !         writeln(chartyp, tab1, '*Bools[] = { "false", "true" };');
  1183.       if usescan then
  1184.           begin
  1185.           writeln;
  1186. --- 8838,8848 ----
  1187.       conflag := false;
  1188.       setused := false;
  1189.       dropset := false;
  1190. !     doarrow := false;
  1191. !     donearr := false;
  1192.       eprogram(top);
  1193.       if usebool then
  1194. !         writeln(static, chartyp, tab1, '*Bools[] = { "false", "true" };');
  1195.       if usescan then
  1196.           begin
  1197.           writeln;
  1198. ***************
  1199. *** 8749,8770 ****
  1200.           begin
  1201.           writeln;
  1202.           writeln(static, 'FILE *');
  1203. !         writeln('Fopen(n, m)');
  1204.           writeln(chartyp, tab1, '*n, *m;');
  1205.           writeln('{');
  1206.           writeln(tab1, 'FILE', tab2, '*f;');
  1207.           writeln(tab1, registr, chartyp, tab1, '*s;');
  1208.           writeln(tab1, static, chartyp, tab1, 'ch = ',
  1209.                           quote, 'A', quote, ';');
  1210. !         writeln(tab1, static, chartyp, tab1, 'tmp[MAXFILENAME];');
  1211. !         writeln(tab1, xtern , inttyp, tab1, 'unlink();'); (* OS *)
  1212.           writeln;
  1213.           writeln(tab1, 'if (n == NULL)');
  1214.           writeln(tab2, 'sprintf(tmp, ', tmpfilename, 'ch++);');
  1215.           writeln(tab1, 'else {');
  1216.           writeln(tab2, 'strncpy(tmp, n, sizeof(tmp));');
  1217.           writeln(tab2, 'for (s = &tmp[sizeof(tmp)-1]; *s == ',
  1218. !             spchr, ' || *s == ', nulchr, '; )');
  1219.           writeln(tab3, '*s-- = ', nulchr, ';');
  1220.           writeln(tab2, 'if (tmp[sizeof(tmp)-1]) {');
  1221.           writeln(tab3, voidcast, 'fprintf(stderr, "Too long filename ',
  1222. --- 8872,8897 ----
  1223.           begin
  1224.           writeln;
  1225.           writeln(static, 'FILE *');
  1226. !         writeln('Fopen(n, l, m)');
  1227.           writeln(chartyp, tab1, '*n, *m;');
  1228. +         writeln(inttyp, tab1, 'l;');
  1229.           writeln('{');
  1230.           writeln(tab1, 'FILE', tab2, '*f;');
  1231.           writeln(tab1, registr, chartyp, tab1, '*s;');
  1232.           writeln(tab1, static, chartyp, tab1, 'ch = ',
  1233.                           quote, 'A', quote, ';');
  1234. !         writeln(tab1, static, chartyp, tab1, 'tmp[', maxfilename, '];');
  1235. !         writeln(tab1, xtern , inttyp, tab1, 'unlink(),'); (* OS *)
  1236. !         writeln(tab3, 'strlen();'); (* OS *)
  1237.           writeln;
  1238.           writeln(tab1, 'if (n == NULL)');
  1239.           writeln(tab2, 'sprintf(tmp, ', tmpfilename, 'ch++);');
  1240.           writeln(tab1, 'else {');
  1241. +         writeln(tab2, 'if (l < 0)');
  1242. +         writeln(tab3, 'l = strlen(n);');
  1243.           writeln(tab2, 'strncpy(tmp, n, sizeof(tmp));');
  1244.           writeln(tab2, 'for (s = &tmp[sizeof(tmp)-1]; *s == ',
  1245. !             spchr, ' || *s == ', nulchr, ' || s - tmp > l; )');
  1246.           writeln(tab3, '*s-- = ', nulchr, ';');
  1247.           writeln(tab2, 'if (tmp[sizeof(tmp)-1]) {');
  1248.           writeln(tab3, voidcast, 'fprintf(stderr, "Too long filename ',
  1249. ***************
  1250. *** 8782,8788 ****
  1251.           writeln(tab2, 'unlink(tmp);');    (* OS *)
  1252.           writeln(tab1, 'return (f);');
  1253.           writeln('}');
  1254. -         writeln(xtern, inttyp, tab1, 'rewind();')
  1255.           end;
  1256.       if setcnt > 0 then
  1257.           econset(setlst, setcnt);
  1258. --- 8909,8914 ----
  1259. ***************
  1260. *** 9098,9106 ****
  1261.           writeln(tab2, '*S1++ = 0;');
  1262.           writeln('}')
  1263.           end;
  1264. !     if usecase then
  1265.           begin
  1266.           writeln;
  1267.           writeln(static, voidtyp);
  1268.           writeln('Caseerror(n)');
  1269.           writeln(tab1, inttyp, tab1, 'n;');
  1270. --- 9224,9263 ----
  1271.           writeln(tab2, '*S1++ = 0;');
  1272.           writeln('}')
  1273.           end;
  1274. !     if usesal then
  1275.           begin
  1276.           writeln;
  1277. +         writeln(static, 'struct Set *');
  1278. +         writeln('Alignset(Sp)');
  1279. +         writeln(tab1, registr, wordtype, tab1, '*Sp;');
  1280. +         writeln('{');
  1281. +         writeln(tab1, static, 'struct Set', tab1, 'tmp;');
  1282. +         writeln(tab1, registr, wordtype, tab1, '*tp = tmp.S;');
  1283. +         writeln(tab1, registr, inttyp, tab2, 'i = *Sp;');
  1284. +         writeln;
  1285. +         writeln(tab1, 'while (i-- >= 0)');
  1286. +         writeln(tab2, '*tp++ = *Sp++;');
  1287. +         writeln(tab1, 'return (&tmp);');
  1288. +         writeln('}')
  1289. +         end;
  1290. +     if usealig then
  1291. +         begin
  1292. +         writeln;
  1293. +         writeln(static, 'struct String *');
  1294. +         writeln('Alignstr(Cp)');
  1295. +         writeln(tab1, registr, chartyp, tab1, '*Cp;');
  1296. +         writeln('{');
  1297. +         writeln(tab1, static, 'struct String', tab1, 'tmp;');
  1298. +         writeln(tab1, registr, chartyp, tab1, '*sp = tmp.A;');
  1299. +         writeln;
  1300. +         writeln(tab1, 'while (*sp++ = *Cp++)');
  1301. +         writeln(tab2, ';');
  1302. +         writeln(tab1, 'return (&tmp);');
  1303. +         writeln('}')
  1304. +         end;
  1305. +     if usecase or usejmps then
  1306. +         begin
  1307. +         writeln;
  1308.           writeln(static, voidtyp);
  1309.           writeln('Caseerror(n)');
  1310.           writeln(tab1, inttyp, tab1, 'n;');
  1311. ***************
  1312. *** 9108,9113 ****
  1313. --- 9265,9271 ----
  1314.           writeln(tab1, voidcast,
  1315.               'fprintf(stderr, "Missing case limb: line %d\n", n);');
  1316.           writeln(tab1, 'exit(1);');
  1317. +         writeln(tab1, '/', '* NOTREACHED *', '/');
  1318.           writeln('}')
  1319.           end;
  1320.       if usemax then
  1321. ***************
  1322. *** 9153,9158 ****
  1323. --- 9311,9318 ----
  1324.       t    : pretyps;
  1325.       d    : predefs;
  1326.   
  1327. +     hx    : packed array [ 1 .. 16 ] of char;
  1328.       (*    Define names in ctable.                    *)
  1329.       procedure defname(cn : cnames; str : keyword);
  1330.   
  1331. ***************
  1332. *** 9328,9339 ****
  1333.   begin    (* initialize *)
  1334.       lineno := 1;
  1335.       colno := 0;
  1336.   
  1337.       initstrstore;
  1338.   
  1339.       setlst := nil;
  1340.       setcnt := 0;
  1341. !     hexdig := '0123456789ABCDEF';
  1342.   
  1343.       symtab := nil;
  1344.       statlvl := 0;
  1345. --- 9488,9501 ----
  1346.   begin    (* initialize *)
  1347.       lineno := 1;
  1348.       colno := 0;
  1349. +     pushed := false;
  1350.   
  1351.       initstrstore;
  1352.   
  1353.       setlst := nil;
  1354.       setcnt := 0;
  1355. !     hx := '0123456789ABCDEF';
  1356. !     unpack(hx, hexdig, 0);
  1357.   
  1358.       symtab := nil;
  1359.       statlvl := 0;
  1360. ***************
  1361. *** 9366,9371 ****
  1362. --- 9528,9535 ----
  1363.   
  1364.       usecomp := false;
  1365.       usemax    := false;
  1366. +     usealig    := false;
  1367. +     usesal    := false;
  1368.   
  1369.       for s := 0 to hashmax do
  1370.           idtab[s] := nil;
  1371. ***************
  1372. *** 9541,9546 ****
  1373. --- 9705,9713 ----
  1374.       defname(cungetc,    'ungetc    ');    (* LIB *)
  1375.       defname(cunion,        'union     ');
  1376.       defname(cunlink,    'unlink    ');    (* OS *)
  1377. +     defname(cfseek,        'fseek     ');    (* LIB *)
  1378. +     defname(cgetchar,    'getchar   ');    (* LIB *)
  1379. +     defname(cputchar,    'putchar   ');    (* LIB *)
  1380.       defname(cunsigned,    'unsigned  ');
  1381.       defname(cwrite,        'write     ');    (* OS *)
  1382.   
  1383. ***************
  1384. *** 9613,9619 ****
  1385.              describing type, fill in constant identifying type *)
  1386.           case t of
  1387.             tboolean:
  1388. !             typnods[t] := deftab[dboolean]; (* scalar type *)
  1389.             tchar:
  1390.               typnods[t] := deftab[dchar]^.tbind;
  1391.             tinteger:
  1392. --- 9780,9786 ----
  1393.              describing type, fill in constant identifying type *)
  1394.           case t of
  1395.             tboolean:
  1396. !             typnods[t] := deftab[dboolean]^.tbind;
  1397.             tchar:
  1398.               typnods[t] := deftab[dchar]^.tbind;
  1399.             tinteger:
  1400. SHAR_EOF
  1401. fi # end of overwriting check
  1402. #    End of shell archive
  1403. exit 0
  1404.  
  1405.  
  1406.